package com.abel.bigwater.kmgw.config

import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.core.userdetails.User
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.provisioning.InMemoryUserDetailsManager

@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
    @Value("{spring.security.user.name}")
    var username: String? = null

    @Value("{spring.security.user.password}")
    var password: String? = null

    override fun configure(http: HttpSecurity?) {
        http!!.csrf().disable()
        http.authorizeRequests().antMatchers("/static/**").permitAll()
                .antMatchers("/**.*", "/").authenticated()
                .and().formLogin().loginPage("/login").successForwardUrl("/").permitAll()
                .and().rememberMe().tokenValiditySeconds(30 * 86400)
                .and().logout().permitAll().invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .and().sessionManagement().maximumSessions(10).expiredUrl("/login")
    }

    override fun userDetailsService(): UserDetailsService {
        return InMemoryUserDetailsManager().apply {
            createUser(User(username, password, emptyList()))
        }
    }

    @Bean
    fun passwordEncoder(): PasswordEncoder {
//        return BCryptPasswordEncoder()

        val pe = object : PasswordEncoder {

            /**
             * Encode the raw password. Generally, a good encoding algorithm applies a SHA-1 or
             * greater hash combined with an 8-byte or greater randomly generated salt.
             */
            override fun encode(rawPassword: CharSequence?): String {
//                val md5Str = DigestUtils.md5DigestAsHex(rawPassword!!.toString().toByteArray(Charsets.UTF_8))
//                return md5Str
                return rawPassword!!.toString()
            }

            /**
             * Verify the encoded password obtained from storage matches the submitted raw
             * password after it too is encoded. Returns true if the passwords match, false if
             * they do not. The stored password itself is never decoded.
             *
             * @param rawPassword the raw password to encode and match
             * @param encodedPassword the encoded password from storage to compare with
             * @return true if the raw password, after encoding, matches the encoded password from
             * storage
             */
            override fun matches(rawPassword: CharSequence?, encodedPassword: String?): Boolean {
//                lgr.info("$rawPassword ?= $encodedPassword")
                return encode(rawPassword) == encodedPassword
            }
        }

        return pe
    }
}